/********************************************************
 *
 * FILE NAME:   plotsignal.h
 *
 * DESCRIPTION:
 *  Display input signal on screen
 *
 ********************************************************/

#ifndef PLOTSIGNAL_H
#define PLOTSIGNAL_H

/********************************************************/
/*              Includes                                */
/********************************************************/

#include "qcustomplot.h"
#include "signalprocessing/signalprocessing.h"
#include "buffer.h"

#include <QQuickPaintedItem>

/********************************************************/
/*              Defines                                 */
/********************************************************/

#define TICK_STEP 2.5

class Plot;
class PlotWorker;

class Plot:public QQuickPaintedItem
{
    friend class PlotWorker;
    Q_OBJECT

    Q_PROPERTY(int signalDuration READ getSignalDuration WRITE setSignalDuration NOTIFY signalDurationChanged)

    Q_PROPERTY(bool signalActive READ isSignalActive WRITE setSignalActivity NOTIFY signalActivityChanged)

    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)

/********************************************************/
/*              Functions Declarations                  */
/********************************************************/
public:

     int getSignalDuration() const { return _signalDuration; }
     void setSignalDuration(double signalDuration);

     QString getName() const { return _name; }
     void setName(QString name);

     bool isSignalActive() const { return _signalActive; }
     void setSignalActivity(bool signalActivity);

    /********************************************************
     * Function Name    :   Plot
     *
     * Description      :   Constructor
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :   QQuickItem *parent = parent
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    explicit Plot( QQuickItem* parent = 0);

    /********************************************************
     * Function Name    :   ~Plot
     *
     * Description      :   Destructor
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    ~Plot();

    /********************************************************
     * Function Name    :   init
     *
     * Description      :   Initialization of all parameters
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    Q_INVOKABLE void init();

    /********************************************************
     * Function Name    :   start
     *
     * Description      :   Start displaying data
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    Q_INVOKABLE void start();

    /********************************************************
     * Function Name    :   getInputSignal
     *
     * Description      :   Get pointer to input signal
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :
     *
     * Returns      	:   Pointer to input signal ( ISignal* )
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    Q_INVOKABLE EXPORT_SIGNAL(_iSignal, ISignal)

    /********************************************************
     * Function Name    :   paint
     *
     * Description      :   Paints content of customPlot
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :   QPainter* painter
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    void paint( QPainter* painter );


private slots:
    void updateQCustomPlotSize();

signals:
    void signalDurationChanged();
    void signalActivityChanged();
    void nameChanged();


/********************************************************/
/*              Variables Declarations                  */
/********************************************************/
private:
    QCustomPlot *_customPlot;
    QThread *_workerThread;
    PlotWorker *_worker;
    ISignal *_iSignal;
    size_t _burstLength;
    QMutex *_plotMutex;
    bool _plotPending;
    bool _signalActive;
    bool _rescaleFlag = false;
    QPixmap *_plotPixmap;
    size_t _xTickNum;
    size_t _yTickNum;
    double _signalAmpRange;
    double _signalDuration;
    size_t _windowWidth;
    double _sampleFreq;
    QString _xLabelText;
    QFont _labelFont;
    QString _name;
    QString _units;
    size_t _sampleNum;

    static size_t _numOfActive;
    static QMutex _numOfActiveMtx;
};

class PlotWorker : public QObject
{

    Q_OBJECT


/********************************************************/
/*              Functions Declarations                  */
/********************************************************/
public:
    explicit PlotWorker(Plot *context);
    ~PlotWorker();

    /********************************************************
     * Function Name    :   maxValue
     *
     * Description      :   Find maximum value in vector
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :   QVector<double> values
     *
     * Returns      	:   Maximum value in vector values
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    double maxValue(QVector<double> values);

signals:
    void replot();


private slots:

    /********************************************************
     * Function Name    :   start
     *
     * Description      :   Start displaying data
     *
     * Side effects     :
     *
     * Comment          :
     *
     * Parameters       :
     *
     * Returns      	:
     *
     * Reviewed by      :   draganmarjanovic10@gmail.com, v_duschan@hotmail.com
     *
     ********************************************************/

    void start();


/********************************************************/
/*              Variables Declarations                  */
/********************************************************/
private:
    Plot *_context;
    size_t _sampleNum;
    size_t _windowWidth;
};

#endif // PLOTSIGNAL_H
